use salvo::prelude::*;
use salvo::oapi::extract::*;
use crate::service;
use crate::models::rbac::role::SafeRole;
use crate::service::rbac::{user_role::UserRoleService, role::RoleService};

#[endpoint(tags("RBAC"), parameters(("user_id", description = "ID of the user to get roles for")))]
async fn get_user_roles(req: &mut Request, user_id: PathParam<String>) -> Result<Json<Vec<SafeRole>>, StatusError> {
    let db = service::conn();
    use crate::utils::tenant::get_tenant_id;
    let tenant_id = get_tenant_id(req).map_err(|e| {
        StatusError::internal_server_error().brief(e.to_string())
    })?.unwrap_or(0);
    
    let role_ids = UserRoleService::find_roles_by_user(db, &user_id, tenant_id).await
        .map_err(|e| StatusError::internal_server_error().brief(e.to_string()))?;
    
    let mut roles = Vec::new();
    for role_id in role_ids {
        if let Some(role) = RoleService::find_by_id(db, &role_id, Some(tenant_id)).await
            .map_err(|e| StatusError::internal_server_error().brief(e.to_string()))? {
            roles.push(SafeRole {
                id: role.id,
                tenant_id: role.tenant_id,
                name: role.name,
                description: role.description,
            });
        }
    }
    Ok(Json(roles))
}

pub fn routes() -> Router {
    Router::with_path("users/{user_id}/roles")
        .hoop(crate::hoops::jwt::auth_hoop(&crate::config::get().jwt))
        .get(get_user_roles)
}
